package com.mobipe.sutto.grizzly;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

import org.glassfish.grizzly.Buffer;
import org.glassfish.grizzly.Connection;
import org.glassfish.grizzly.filterchain.BaseFilter;
import org.glassfish.grizzly.filterchain.FilterChainContext;
import org.glassfish.grizzly.filterchain.NextAction;

import com.mobipe.sutto.core.AbstractServer;
import com.mobipe.sutto.core.InterfaceServerHandler;
import com.mobipe.sutto.core.ProtocolProcess;

/**
 * @author kohachiro
 * 
 */
public class ServerHandler extends BaseFilter implements InterfaceServerHandler {
	private static AtomicInteger id = new AtomicInteger(0);
	private final static Map<FilterChainContext, Integer> connections = new ConcurrentHashMap<FilterChainContext, Integer>();
	
	public ServerHandler(){
		AbstractServer.callbackHandler=this;
	}
	@Override
	public NextAction handleConnect(FilterChainContext ctx) throws IOException {
		connections.put(ctx,id.incrementAndGet());
		return handleConnect(ctx);
	}

	@Override
	public NextAction handleClose(FilterChainContext ctx) throws IOException {
		connections.remove(ctx.getConnection());
		return super.handleClose(ctx);
		
	}

	@Override
	public NextAction handleRead(FilterChainContext ctx) throws IOException {;
		ProtocolProcess.protocolHandler(((Buffer) ctx.getMessage()).toByteBuffer(), ctx.getConnection());
		return ctx.getStopAction();
	}

	@Override
	public void sendResponse(ByteBuffer message, Object channel)
			throws Exception {
		Buffer buf=((Connection<?>) channel).getTransport().getMemoryManager().allocate(message.remaining());
		buf.allowBufferDispose(true);
		buf.put(message);
		((Connection<?>) channel).write(buf.flip());
	}
	
	@Override
	public void sendResponseClose(ByteBuffer message, Object channel)
			throws Exception {
		Buffer buf=((Connection<?>) channel).getTransport().getMemoryManager().allocate(message.remaining());
		buf.allowBufferDispose(true);
		buf.put(message);
		((Connection<?>) channel).write(buf.flip());
		((Connection<?>) channel).close();
	}

	@Override
	public int getId(Object channel) {
		return connections.get(channel);
	}

}
